
import re
from ..library import simplejson as json
import mimetypes
from datetime import datetime
from google.appengine.api import users
from ..library.BeautifulSoup import BeautifulSoup, Tag, NavigableString
from layeredcontent.handler.handlers import RequestHandler
from layeredcontent.model import *


javascript_includes = [
  '/lc/assets/js/jquery.js',
  '/lc/assets/js/edit-page.js',
  'http://ajax.googleapis.com/ajax/libs/prototype/1.6.0.3/prototype.js',
  '/lc/assets/js/wysihat-0.2.js',
]


# Resources

class ResourceHandler(RequestHandler):
  
  urls = {
    '/lc/resources/': 'list',
  }
  
  
  def list(self):
    query = Resource.all().order('-created')
    self.render('resource-list.html', {'resources': query.fetch(21), 'port': self.get_portstr()})
  
  
  
  def get(self):
    
    #handle regular actions first
    if self.findAction('get'):
      return
    
    if self.request.path[0:3] == '/lc':
      return self.not_found()
    
    path = self.request.path
    domain = re.sub(r'^[^/]*//([^/:]+).*$', r'\1', self.request.url)
    now = datetime.now().replace(microsecond=0).isoformat(' ')
    
    if self.request.get('fields', 'no') != 'no' and self.is_admin():
      results = Page.all().filter('domain =', domain).filter('path =', path).fetch(1)
      if not len(results):
        return self.resource_not_found()
      
      page = results[0]
      xml = BeautifulSoup(page.template.xml)
      
      fields = xml('field')
      fields = map(lambda xml:{
        'title': xml['title'],
        'name': xml['name'],
        'type': xml['type'],
        'path': xml['path'],
      }, fields)
      
      return self.response.out.write(json.dumps(fields))
    
    results = Resource.gql("WHERE domain = :domain AND path = :path AND publish < DATETIME(:publish) ORDER BY publish DESC LIMIT 1", domain=domain, path=path, publish=now).fetch(1)
    if not len(results):
      return self.resource_not_found()
    
    resource = results[0]
    
    pieces = resource.modified.ctime().split()
    pieces = pieces[0:1] + pieces[2:3] + pieces[1:2] + pieces[4:5] + pieces[3:4]
    last_modified = '%s, %s %s %s %s GMT' % tuple(pieces)
    if_modified = self.request.headers.get('If-Modified-Since')
    
    if not resource.mime.startswith('text/html'):
      self.response.headers['Cache-Control'] = 'public, max-age=600'
    
    if last_modified == if_modified:
      return self.error(304)
    
    self.response.headers['Last-Modified'] = last_modified
    self.response.headers['Content-Type'] = resource.mime.encode('utf-8')
    if resource.mime.startswith('text/html'):
      self.render_page(resource.content)
    else:
      self.response.out.write(resource.content)


  def post(self):
    
    if not self.require_admin():
      return
    
    #handle regular actions first
    if self.findAction('post'):
      return
    
    domain = re.sub(r'^[^/]*//([^/:]+).*$', r'\1', self.request.url)
    content = self.request.get('content')
    
    if not content:
      page = Page()
      page.template = Template.get(self.request.get('template'))
      page.title = self.request.get('title')
      page.author = users.get_current_user()
      page.domain = domain
      page.path = self.request.path
      page.put()
      content = page.template.html.encode('utf-8')
      
    resource = Resource()
    resource.content = db.Blob(content)
    resource.author = users.get_current_user()
    resource.domain = domain
    resource.path = self.request.path
    mime, encoding = mimetypes.guess_type(self.request.path)
    if mime:
      resource.mime = mime
    resource.put()
    self.redirect(resource.path)

  def put(self):
    
    if not self.require_admin():
      return
    
    path = self.request.path
    domain = re.sub(r'^[^/]*//([^/:]+).*$', r'\1', self.request.url)
    results = Resource.all().filter('domain =', domain).filter('path =', path).fetch(1)
    if not len(results):
        return self.resource_not_found()
    
    resource = results[0]
    content = self.request.body
    content = content.replace('\\', '\\\\')
    replaceRE = re.compile(r'(<body[^>]*>).*(</body>)', re.DOTALL)
    content = replaceRE.sub(r'\1' + content + r'\2', resource.content)
    resource.content = db.Blob(content)
    resource.author = users.get_current_user()
    resource.put()
  
  

  def delete(self):
    
    if not self.require_admin():
      return
    
    self.response.out.write('Hello world!')
  
  
  def render_page(self, html, vars = {}):
    if self.is_admin():
      html = BeautifulSoup(html)
      scripts = map(lambda url:'<script type="text/javascript" src="%s"></script>' % url, javascript_includes)
      html.head.insert(len(html.head.contents), BeautifulSoup('\n'.join(scripts)))
      html = html.prettify()
    self.render_source(html, vars)
  
  def resource_not_found(self):
    self.error(404)
    if self.is_admin():
      templates = Template.all().order('name').fetch(100)
      title = self.request.path.split('/').pop().replace('-', ' ').title()
      self.render('admin-404.html', {'templates': templates, 'path': self.request.path, 'title': title})
    else:
      self.render('404.html')
